#pragma once

#include <XnCppWrapper.h>
#include <string>
#include "Vector3df.h"


/*static enum OldKey {
	A=3, B=5, C=0, D=2, E=4, F=11, G=1, As=10, Cs=7, Ds=9, Fs=6, Gs=8, Ab=8, Bb=10, Db=7, Eb=9, Gb=6, None=20
};*/

static enum Key {
	A=0, Bb=1, B=2, C=3, Db=4, D=5, Eb=6, E=7, F=8, Gb=9, G=10, Ab=11, None=20
}; 

/* Note struct, for easy parsing into strings for the player
	A,D = attack & decay, [0-127]. For now, the same value.
	Oct = Octave (0-10). Middle C = octave 5. 
	Dr = Duration (1-8), need to adjust this if the measure changes size again
	k = enum value (above) for the current key. Actual key value, not key signature?
			Should stick with A - G, let the specified key signature change to minor. 

	Player needs a lookup table for root of chord? No, should be ok with just A, etc...?
*/
struct note {
	int A,D; 
	int Oct;
	int Dr;
	Key k;
};

bool NoteEqual(note A, note B);


struct pt {
	pt() {clk = true; end = false; evl = false;}
	bool clk; //True if clockwise
	bool end; //Endpoint
	bool evl; //True if already evaled
	double dst; //distance away from surrounding pts
};

std::string lookupKey(Key root, int prog);
//std::vector<Key> lookupAllKeys(Key root, std::string mode);
Key lookupAllKeys(Key root, std::string mode, Key* chord, float ch);

//Draw a rectangle 
void DrawRect(double cx, double cy, double width=8.);
//Overload for XnPoint3D? might be easier, let this function split it up...
void DrawRect(XnPoint3D pt, double width=8.);


void printw (float x, float y, float z, char* format, ...);
void printw (float x, float y, float z, std::string formatStr, ...);

std::string ftos(float st);
const char* ftoa(float st);
std::string itos(int i);

float mid(float a, float b);

float lineDist(XnVector3D Pt, XnVector3D first, XnVector3D last);
float dist(XnVector3D a, XnVector3D b);
float dist2D(float x1, float y1, float x2, float y2);

float newChord(Vector3df pos, int wx, int wy);

float minmax(float min, float value, float max);

float scale(float min, float value, float max);//Scales a # to between 0 and 1
float newScale(float newmin, float newmax, float oldmin, float oldmax, float value);


std::string addWait(int i, bool rest);

std::string noteToString(note n);
std::string keyToString(Key k);
std::string roman(int c);//Converts int to roman numeral... only I - VI, so easy


float angle(XnVector3D mid, XnVector3D first, XnVector3D last);

void adjust(float &var, float add);

void DrawOval (float x_center, float y_center, float w, float h, int n, bool fill);
void DrawCircle(float cx, float cy, float r, int num_segments);
void DrawRomNums(float cx, float cy, float r);